from decimal import Decimal

import xmltodict
from flask import Blueprint, request, jsonify, current_app
import datetime
import time
import json

from flask_jwt_extended import jwt_required, get_jwt_identity, get_jwt

from app.core.extensions import db
from app.models.commission import CommissionLog
from app.models.user import User, ShareRelation
from app.models.agents import (
    Plan, Order, PaymentLog, PaymentNotification,
    UsageRecord, ActivationCode
)
from app.services.auth import token_required
from app.config import exConfig

pay_bp = Blueprint('pay', __name__)

from app.services.wxPayService import WeixinPayV2, WeixinPayV3


def get_tenant_wxpay():
    """获取当前租户的微信支付实例"""
    from app.services.tenant_config_service import get_tenant_config
    tenant_config_service = get_tenant_config()

    # 获取微信支付配置
    pay_config = tenant_config_service.get_wechat_pay_config()

    # 检查必要配置
    if not pay_config.get('mch_id') or not pay_config.get('api_key'):
        raise ValueError("租户微信支付配置不完整")

    return WeixinPayV2(pay_config)


def get_tenant_wxpay_v3():
    """获取当前租户的微信支付V3实例"""
    from app.services.tenant_config_service import get_tenant_config
    tenant_config_service = get_tenant_config()

    # 获取微信支付配置
    pay_config = tenant_config_service.get_wechat_gzh_config()

    # 检查必要配置
    if not pay_config.get('mch_id') or not pay_config.get('api_key'):
        raise ValueError("租户微信支付配置不完整")

    return WeixinPayV3(pay_config)


@pay_bp.record
def record_params(setup_state):
    pass


@pay_bp.route('/plans', methods=['GET'])
@jwt_required()
def get_plans():
    """获取套餐列表"""
    try:

        claims = get_jwt()
        tenant_id = claims.get("tenant_id")

        plans = Plan.query.filter_by(status=1,tenant_id=tenant_id).order_by(Plan.sort.asc(), Plan.id.asc()).all()
        return jsonify({
            "code": 1,
            "msg": "获取成功",
            "data": {
                "list": [plan.to_dict() for plan in plans]
            }
        })
    except Exception as e:
        current_app.logger.error(f"获取套餐列表失败: {str(e)}")
        return jsonify({"code": 0, "msg": f"服务器错误: {str(e)}"})


@pay_bp.route('/order/create', methods=['POST'])
# @token_required
def create_order():
    """创建支付订单"""
    try:
        data = request.get_json()
        user_id = data.get('user_id')
        plan_id = data.get('plan_id')
        platform = data.get('platform')
        if not isinstance(user_id, int) or not isinstance(plan_id, int):
            return jsonify({"code": 0, "msg": "参数类型错误"})
        if not user_id or not plan_id:
            return jsonify({"code": 0, "msg": "缺少必要参数"})
        if platform not in ["H5", "MP"]:  # MP = Mini Program
            return jsonify({"code": 0, "msg": "非法的支付平台"})
        plan = Plan.query.get(plan_id)
        if not plan:
            return jsonify({"code": 0, "msg": "套餐不存在"})
        if not plan.status:
            return jsonify({"code": 0, "msg": "该套餐已下架"})
        user = User.query.get(user_id)
        if not user:
            return jsonify({"code": 0, "msg": "用户不存在"})

        wxpay = get_tenant_wxpay()
        gwxpay = get_tenant_wxpay_v3()

        if platform == "H5":
            openid = user.gzh_open_id
        elif platform == "MP":
            openid = user.mp_open_id
        if not openid:
            return jsonify({"code": 0, "msg": "用户未绑定微信账号"})
        user_id_str = str(user_id)
        suffix = user_id_str[-4:] if len(user_id_str) >= 4 else user_id_str
        order_no = f"ORD{int(time.time())}{suffix}"

        amount = float(plan.amount)
        total_fee = int(amount * 100)  # 转成分

        if user_id_str == "418":
            amount = Decimal('0.01')  # 设置为 0.01 元
            total_fee = 1
        else:
            print("=====================")
        order = Order(
            id=order_no,
            user_id=user_id,
            amount=amount,
            total_fee=total_fee,
            plan_id=plan_id,
            times=plan.times,
            title=f"学法减分次数-{plan.name}",
            status="PENDING",
            ip=request.remote_addr or "127.0.0.1",
            openid=openid
        )
        db.session.add(order)
        db.session.commit()

        # 调用微信统一下单
        try:
            if platform == "H5":
                print("H5支付")
                pay_params = gwxpay.create_unified_order(
                    openid=openid,
                    out_trade_no=order_no,
                    total_fee=total_fee,
                    body=order.title,
                    notify_url=exConfig.WXPAY_NOTIFY_URL,
                    spbill_create_ip=request.remote_addr or "127.0.0.1"
                )
                order.platform_type = "H5"
                pay_params["appId"] = gwxpay.appid
            else:
                pay_params = wxpay.create_unified_order(
                    openid=openid,
                    out_trade_no=order_no,
                    total_fee=total_fee,
                    body=order.title,
                    notify_url=exConfig.WXPAY_NOTIFY_URL,
                    spbill_create_ip=request.remote_addr or "127.0.0.1"
                )
                order.platform_type = "MP"
                pay_params["appId"] = wxpay.appid
            current_app.logger.info(f"统一下单成功，支付参数: {pay_params}")

            # 记录支付日志
            payment_log = PaymentLog(
                order_id=order_no,
                amount=amount,
                payment_type="待支付",
                status="待支付",
                raw_data=json.dumps(pay_params)
            )
            db.session.add(payment_log)

            # 更新订单预支付ID
            order.prepay_id = pay_params.get("package", "")

            db.session.commit()

            return jsonify({
                "code": 1,
                "msg": "创建订单成功",
                "data": {
                    "order_id": order_no,
                    "payment_params": pay_params
                }
            })

        except Exception as e:
            current_app.logger.error(f"统一下单失败: {str(e)}")
            order.status = "FAILED"
            db.session.commit()
            return jsonify({"code": 0, "msg": "统一下单失败"}), 500

    except Exception as e:
        current_app.logger.error(f"创建订单错误: {str(e)}")
        return jsonify({"code": 0, "msg": f"服务器错误: {str(e)}"})


@pay_bp.route('/notify', methods=['POST'])
def pay_notify():
    """支付结果通知处理"""
    try:
        # 获取微信支付回调数据
        xml_data = request.data.decode('utf-8')
        notify_data = xmltodict.parse(xml_data).get('xml', {})
        bank_type = notify_data.get("bank_type")  # 例如：'CFT'
        out_trade_no = notify_data.get('out_trade_no')
        transaction_id = notify_data.get('transaction_id')
        # 处理回调
        result = notify_data.get('result_code')
        # 记录原始通知
        notification = PaymentNotification(
            order_id=out_trade_no,  # 暂时设为unknown，后面会更新
            notification_type="PAY",
            status="RECEIVED",
            raw_data=xml_data,
            processed=False
        )
        db.session.add(notification)
        db.session.commit()

        # 更新通知记录
        if result == 'SUCCESS':
            notification.order_id = out_trade_no
            notification.transaction_id = transaction_id
            notification.status = "SUCCESS"

            # 查找订单
            order = Order.query.get(out_trade_no)
            if order:
                # 检查订单是否已处理过
                if order.status == "PAID":
                    notification.processed = True
                    db.session.commit()
                    return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>"

                # 更新订单状态
                order.status = "PAID"
                order.paid_time = datetime.datetime.now()
                order.notify_time = datetime.datetime.now()
                order.transaction_id = transaction_id

                # 记录支付日志
                payment_log = PaymentLog(
                    order_id=out_trade_no,
                    transaction_id=transaction_id,
                    amount=order.amount,
                    payment_type=bank_type,  # 支付方式
                    status="SUCCESS",
                    raw_data=json.dumps(result)
                )
                db.session.add(payment_log)

                # 增加用户使用次数
                user = User.query.get(order.user_id)
                if user:
                    # 记录使用次数变更
                    usage_record = UsageRecord(
                        user_id=user.user_id,
                        source_type="ORDER",
                        source_id=out_trade_no,
                        times=order.times,
                        remark=f"购买套餐: {order.title}"
                    )
                    db.session.add(usage_record)

                    # 更新用户使用次数
                    user.usage_count += order.times + 5

                    # 标记通知为已处理
                    notification.processed = True
                    db.session.commit()

                    current_app.logger.info(
                        f"订单 {out_trade_no} 支付成功，用户 {user.user_id} 使用次数增加 {order.times}")

                    # 分销
                    commissionUser = ShareRelation.query.filter_by(invitee_id=order.user_id).first()
                    if commissionUser:
                        levelUser = User.query.get(commissionUser.sharer_id)
                        if levelUser and levelUser.role == "commission":
                            # 设置提成比例，例如 10%
                            # 默认提成比例为 10%，用小数表示（0.1）
                            commission_rate = Decimal(
                                levelUser.distribution_rate) / 100 if levelUser.distribution_rate else Decimal('0.10')

                            commission_amount = round(Decimal(order.amount) * commission_rate, 2)

                            commission_log = CommissionLog(
                                order_id=order.id,
                                from_user_id=order.user_id,
                                to_user_id=levelUser.user_id,
                                amount=commission_amount,
                                rate=commission_rate  # 存入数据库的是“百分比”，如 10.00
                            )
                            db.session.add(commission_log)

                            # 更新邀请人钱包余额（如果你有 balance 字段）
                            if hasattr(levelUser, 'balance'):
                                levelUser.balance += commission_amount

                            # 一起提交
                            db.session.commit()

                            current_app.logger.info(
                                f"用户 {order.user_id} 付款成功，分销佣金 {commission_amount} 发放给邀请人 {levelUser.user_id}")

            else:
                current_app.logger.warning(f"支付通知: 找不到订单 {out_trade_no}")

            return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>"
        else:
            notification.status = "FAIL"
            notification.processed = True
            db.session.commit()

            current_app.logger.error(f"支付通知处理失败: {result}")
            return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[处理失败]]></return_msg></xml>"

    except Exception as e:
        current_app.logger.error(f"处理支付通知错误: {str(e)}")
        return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[服务器错误]]></return_msg></xml>"


@pay_bp.route('/order/query', methods=['GET'])
@token_required
def query_order():
    """查询订单状态"""
    try:
        order_id = request.args.get('order_id')

        if not order_id:
            return jsonify({"code": 0, "msg": "缺少订单ID"})

        # 查询本地订单
        order = Order.query.get(order_id)

        if not order:
            # 如果本地没有记录，调用微信查询
            result = wxpay.query_order(out_trade_no=order_id)

            if result.get('status') == 'success':
                trade_state = result.get('trade_state')
                return jsonify({
                    "code": 1,
                    "msg": "查询成功",
                    "data": {
                        "order_id": order_id,
                        "status": "PAID" if trade_state == "SUCCESS" else "PENDING",
                        "is_paid": trade_state == "SUCCESS",
                        "trade_state": trade_state,
                        "trade_state_desc": result.get('trade_state_desc', '')
                    }
                })
            else:
                return jsonify({
                    "code": 0,
                    "msg": "订单不存在或查询失败"
                })
        else:
            # 如果订单状态为PENDING且创建时间超过5分钟，则查询微信支付状态
            is_pending_timeout = (order.status == "PENDING" and
                                  (datetime.datetime.now() - order.create_time).total_seconds() > 300)

            if is_pending_timeout:
                result = wxpay.query_order(out_trade_no=order_id)

                if result.get('status') == 'success':
                    trade_state = result.get('trade_state')

                    # 如果微信返回支付成功，但本地未处理，则更新本地订单
                    if trade_state == "SUCCESS" and order.status != "PAID":
                        order.status = "PAID"
                        order.paid_time = datetime.datetime.now()
                        order.transaction_id = result.get('transaction_id')

                        # 记录支付日志
                        payment_log = PaymentLog(
                            order_id=order_id,
                            transaction_id=result.get('transaction_id'),
                            amount=order.amount,
                            payment_type="WXPAY",
                            status="SUCCESS",
                            raw_data=json.dumps(result)
                        )
                        db.session.add(payment_log)

                        # 增加用户使用次数
                        user = User.query.get(order.user_id)
                        if user:
                            # 记录使用次数变更
                            usage_record = UsageRecord(
                                user_id=user.user_id,
                                source_type="ORDER",
                                source_id=order_id,
                                times=order.times,
                                remark=f"购买套餐: {order.title}"
                            )
                            db.session.add(usage_record)

                            # 更新用户使用次数
                            user.usage_count += order.times
                            db.session.commit()

            # 返回本地订单状态
            return jsonify({
                "code": 1,
                "msg": "查询成功",
                "data": {
                    "order_id": order_id,
                    "status": order.status,
                    "is_paid": order.status == "PAID",
                    "create_time": order.create_time.strftime('%Y-%m-%d %H:%M:%S'),
                    "paid_time": order.paid_time.strftime('%Y-%m-%d %H:%M:%S') if order.paid_time else None
                }
            })

    except Exception as e:
        current_app.logger.error(f"查询订单状态错误: {str(e)}")
        return jsonify({"code": 0, "msg": f"服务器错误: {str(e)}"})


@pay_bp.route('/user/orders', methods=['GET'])
@token_required
def get_user_orders():
    """获取用户订单记录"""
    try:
        user_id = request.args.get('user_id')
        page = int(request.args.get('page', 1))
        limit = int(request.args.get('limit', 10))

        if not user_id:
            return jsonify({"code": 0, "msg": "缺少用户ID"})

        # 分页查询订单
        pagination = Order.query.filter_by(user_id=user_id).order_by(
            Order.create_time.desc()
        ).paginate(page=page, per_page=limit, error_out=False)

        orders = []
        for order in pagination.items:
            # 获取套餐信息
            plan = None
            if order.plan_id:
                plan = Plan.query.get(order.plan_id)

            order_dict = order.to_dict()
            order_dict['plan_name'] = plan.name if plan else None
            orders.append(order_dict)

        return jsonify({
            "code": 1,
            "msg": "获取成功",
            "data": {
                "total": pagination.total,
                "list": orders
            }
        })

    except Exception as e:
        current_app.logger.error(f"获取用户订单记录错误: {str(e)}")
        return jsonify({"code": 0, "msg": f"服务器错误: {str(e)}"})


@pay_bp.route('/admin/create_activation_code', methods=['POST'])
@token_required
def create_activation_code():
    """创建激活码接口"""
    data = request.get_json()

    # 获取参数
    count = data.get('count', 1)  # 默认创建1个
    usage_count = data.get('usage_count', 10)  # 默认增加10次使用次数
    expire_days = data.get('expire_days')  # 过期时间(天)，可选
    remark = data.get('remark', '')  # 备注，可选

    try:
        # 生成指定数量的激活码
        created_codes = []
        for _ in range(count):
            # 生成16位随机字符串作为激活码
            import random
            import string
            code_str = ''.join(random.choices(string.ascii_uppercase + string.digits, k=16))

            # 计算过期时间
            expire_time = None
            if expire_days:
                expire_time = datetime.datetime.now() + datetime.timedelta(days=expire_days)

            # 创建激活码对象
            code = ActivationCode(
                code=code_str,
                usage_count=usage_count,
                expire_time=expire_time,
                remark=remark
            )

            db.session.add(code)
            created_codes.append(code_str)

        db.session.commit()

        return jsonify({
            "code": 1,
            "msg": f"成功创建{count}个激活码",
            "data": {
                "codes": created_codes
            }
        })

    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"创建激活码失败: {str(e)}")
        return jsonify({"code": 0, "msg": f"创建激活码失败: {str(e)}"})
